<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!-- 左侧用户信息 -->
      <el-col :span="6" :xs="24">
        <el-card class="box-card">
          <template #header>
            <div class="card-header">
              <span>个人信息</span>
            </div>
          </template>
          <div class="text-center">
            <el-avatar :size="100" :src="user.avatar" />
            <div class="user-info">
              <h2>{{ user.realName || user.username }}</h2>
              <div class="user-dept">{{ user.deptName || '未分配部门' }}</div>
              <div class="user-role">{{ user.roleName || '未分配角色' }}</div>
            </div>
          </div>
          <div class="user-statistic">
            <div class="statistic-item">
              <div class="statistic-number">{{ user.messageCount || 0 }}</div>
              <div class="statistic-title">消息</div>
            </div>
            <div class="statistic-item">
              <div class="statistic-number">{{ user.taskCount || 0 }}</div>
              <div class="statistic-title">任务</div>
            </div>
            <div class="statistic-item">
              <div class="statistic-number">{{ user.noticeCount || 0 }}</div>
              <div class="statistic-title">通知</div>
            </div>
          </div>
        </el-card>
      </el-col>
      
      <!-- 右侧选项卡 -->
      <el-col :span="18" :xs="24">
        <el-card>
          <el-tabs v-model="activeTab">
            <!-- 基本资料 -->
            <el-tab-pane label="基本资料" name="basic">
              <el-form 
                ref="basicFormRef" 
                :model="userForm" 
                :rules="basicRules" 
                label-width="100px"
                class="basic-form"
              >
                <el-form-item label="用户昵称" prop="nickname">
                  <el-input v-model="userForm.nickname" maxlength="30" />
                </el-form-item>
                <el-form-item label="真实姓名" prop="realName">
                  <el-input v-model="userForm.realName" maxlength="30" />
                </el-form-item>
                <el-form-item label="手机号码" prop="phone">
                  <el-input v-model="userForm.phone" maxlength="11" />
                </el-form-item>
                <el-form-item label="邮箱" prop="email">
                  <el-input v-model="userForm.email" maxlength="50" />
                </el-form-item>
                <el-form-item label="性别" prop="gender">
                  <el-radio-group v-model="userForm.gender">
                    <el-radio :label="1">男</el-radio>
                    <el-radio :label="2">女</el-radio>
                    <el-radio :label="0">保密</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" @click="updateBasicInfo">保存</el-button>
                </el-form-item>
              </el-form>
            </el-tab-pane>
            
            <!-- 修改密码 -->
            <el-tab-pane label="修改密码" name="password">
              <el-form 
                ref="passwordFormRef" 
                :model="passwordForm" 
                :rules="passwordRules" 
                label-width="100px"
                class="password-form"
              >
                <el-form-item label="旧密码" prop="oldPassword">
                  <el-input 
                    v-model="passwordForm.oldPassword" 
                    type="password" 
                    placeholder="请输入旧密码" 
                    show-password
                  />
                </el-form-item>
                <el-form-item label="新密码" prop="newPassword">
                  <el-input 
                    v-model="passwordForm.newPassword" 
                    type="password" 
                    placeholder="请输入新密码" 
                    show-password
                  />
                </el-form-item>
                <el-form-item label="确认密码" prop="confirmPassword">
                  <el-input 
                    v-model="passwordForm.confirmPassword" 
                    type="password" 
                    placeholder="请确认新密码" 
                    show-password
                  />
                </el-form-item>
                <el-form-item>
                  <el-button type="primary" @click="updatePassword">保存</el-button>
                </el-form-item>
              </el-form>
            </el-tab-pane>
            
            <!-- 修改头像 -->
            <el-tab-pane label="修改头像" name="avatar">
              <div class="avatar-uploader">
                <div class="avatar-container">
                  <div class="cropper-container">
                    <vue-cropper
                      ref="cropperRef"
                      :img="cropperOptions.img"
                      :output-size="cropperOptions.outputSize"
                      :output-type="cropperOptions.outputType"
                      :info="cropperOptions.info"
                      :full="cropperOptions.full"
                      :fixed="cropperOptions.fixed"
                      :fixed-number="cropperOptions.fixedNumber"
                      :canMove="cropperOptions.canMove"
                      :canMoveBox="cropperOptions.canMoveBox"
                      :original="cropperOptions.original"
                      :auto-crop="cropperOptions.autoCrop"
                      :auto-crop-width="cropperOptions.autoCropWidth"
                      :auto-crop-height="cropperOptions.autoCropHeight"
                      :center-box="cropperOptions.centerBox"
                      @realTime="realTime"
                      v-if="cropperVisible"
                    />
                  </div>
                  <div class="preview-container">
                    <div class="preview-title">头像预览</div>
                    <div class="preview-box large" :style="preview.div"></div>
                    <div class="preview-box small" :style="preview.div"></div>
                  </div>
                </div>

                <div class="avatar-controls">
                  <el-form label-width="100px">
                    <el-form-item>
                      <el-upload
                        class="avatar-upload"
                        action="#"
                        :before-upload="beforeUpload"
                        :show-file-list="false"
                        accept=".jpg,.png,.jpeg,.gif"
                      >
                        <el-button type="primary">选择图片</el-button>
                      </el-upload>
                    </el-form-item>
                    <el-form-item label="旋转调节">
                      <el-button-group>
                        <el-button type="primary" icon="Refresh-left" @click="rotateLeft" />
                        <el-button type="primary" icon="Refresh-right" @click="rotateRight" />
                      </el-button-group>
                    </el-form-item>
                    <el-form-item label="缩放调节">
                      <el-button-group>
                        <el-button type="primary" icon="ZoomIn" @click="zoomIn" />
                        <el-button type="primary" icon="ZoomOut" @click="zoomOut" />
                      </el-button-group>
                    </el-form-item>
                    <el-form-item>
                      <el-button type="primary" @click="uploadAvatar">上传头像</el-button>
                    </el-form-item>
                  </el-form>
                </div>
              </div>
            </el-tab-pane>
          </el-tabs>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/stores/user'
import { getUserInfo, updateUser, updateUserPassword, uploadUserAvatar } from '@/api/user'
import { validEmail, validPhone } from '@/utils/validate'

// 引入图片裁剪组件
import VueCropper from 'vue-cropper'
import 'vue-cropper/dist/index.css'

const userStore = useUserStore()

// 基本信息
const user = reactive({
  id: 0,
  username: '',
  nickname: '',
  realName: '',
  gender: 0,
  phone: '',
  email: '',
  avatar: '',
  deptName: '',
  roleName: '',
  messageCount: 0,
  taskCount: 0,
  noticeCount: 0
})

// 表单数据
const userForm = reactive({
  nickname: '',
  realName: '',
  gender: 0,
  phone: '',
  email: ''
})

// 密码表单
const passwordForm = reactive({
  oldPassword: '',
  newPassword: '',
  confirmPassword: ''
})

// 表单验证规则
const basicRules = {
  nickname: [
    { required: true, message: '用户昵称不能为空', trigger: 'blur' },
    { min: 2, max: 30, message: '用户昵称长度必须介于 2 和 30 之间', trigger: 'blur' }
  ],
  realName: [
    { required: true, message: '真实姓名不能为空', trigger: 'blur' },
    { min: 2, max: 30, message: '真实姓名长度必须介于 2 和 30 之间', trigger: 'blur' }
  ],
  phone: [
    { validator: (rule, value, callback) => {
      if (value && !validPhone(value)) {
        callback(new Error('请输入正确的手机号码'))
      } else {
        callback()
      }
    }, trigger: 'blur' }
  ],
  email: [
    { validator: (rule, value, callback) => {
      if (value && !validEmail(value)) {
        callback(new Error('请输入正确的邮箱地址'))
      } else {
        callback()
      }
    }, trigger: 'blur' }
  ]
}

const passwordRules = {
  oldPassword: [
    { required: true, message: '旧密码不能为空', trigger: 'blur' },
    { min: 6, max: 20, message: '密码长度必须介于 6 和 20 之间', trigger: 'blur' }
  ],
  newPassword: [
    { required: true, message: '新密码不能为空', trigger: 'blur' },
    { min: 6, max: 20, message: '密码长度必须介于 6 和 20 之间', trigger: 'blur' }
  ],
  confirmPassword: [
    { required: true, message: '确认密码不能为空', trigger: 'blur' },
    { min: 6, max: 20, message: '密码长度必须介于 6 和 20 之间', trigger: 'blur' },
    { validator: (rule, value, callback) => {
      if (value !== passwordForm.newPassword) {
        callback(new Error('两次输入的密码不一致'))
      } else {
        callback()
      }
    }, trigger: 'blur' }
  ]
}

// 其他数据
const activeTab = ref('basic')
const basicFormRef = ref(null)
const passwordFormRef = ref(null)
const cropperRef = ref(null)
const cropperVisible = ref(false)
const loading = ref(false)
const preview = reactive({ div: {} })

// 裁剪组件配置
const cropperOptions = reactive({
  img: '', // 裁剪图片的地址
  outputSize: 1, // 裁剪生成图片的质量(可选0.1 - 1)
  outputType: 'png', // 裁剪生成图片的格式
  info: true, // 裁剪框的大小信息
  full: true, // 输出原图比例裁剪图片
  fixed: true, // 是否开启截图框宽高固定比例
  fixedNumber: [1, 1], // 截图框的宽高比例
  canMove: true, // 上传图片是否可以移动
  canMoveBox: true, // 截图框能否拖动
  original: false, // 上传图片按照原始比例渲染
  autoCrop: true, // 是否默认生成截图框
  autoCropWidth: 200, // 默认生成截图框宽度
  autoCropHeight: 200, // 默认生成截图框高度
  centerBox: true // 截图框是否被限制在图片里面
})

// 获取用户信息
const getUser = async () => {
  try {
    const res = await getUserInfo()
    Object.assign(user, res.data)
    // 复制表单值
    userForm.nickname = user.nickname
    userForm.realName = user.realName
    userForm.gender = user.gender
    userForm.phone = user.phone
    userForm.email = user.email
  } catch (error) {
    console.error('获取用户信息失败:', error)
  }
}

// 更新基本信息
const updateBasicInfo = () => {
  basicFormRef.value.validate(async (valid) => {
    if (valid) {
      try {
        loading.value = true
        await updateUser(user.id, userForm)
        ElMessage.success('个人信息修改成功')
        // 更新store中的用户信息
        userStore.setRealName(userForm.realName)
        Object.assign(user, userForm)
      } catch (error) {
        console.error('更新个人信息失败:', error)
        ElMessage.error('更新个人信息失败')
      } finally {
        loading.value = false
      }
    }
  })
}

// 修改密码
const updatePassword = () => {
  passwordFormRef.value.validate(async (valid) => {
    if (valid) {
      try {
        loading.value = true
        await updateUserPassword({
          oldPassword: passwordForm.oldPassword,
          newPassword: passwordForm.newPassword
        })
        ElMessage.success('密码修改成功')
        // 清空表单
        passwordForm.oldPassword = ''
        passwordForm.newPassword = ''
        passwordForm.confirmPassword = ''
        passwordFormRef.value.resetFields()
      } catch (error) {
        console.error('修改密码失败:', error)
        ElMessage.error('修改密码失败')
      } finally {
        loading.value = false
      }
    }
  })
}

// 上传前校验
const beforeUpload = (file) => {
  const isImage = /\.(jpg|jpeg|png|gif)$/.test(file.name.toLowerCase())
  const isLt2M = file.size / 1024 / 1024 < 2
  
  if (!isImage) {
    ElMessage.error('上传头像图片只能是 JPG/PNG/GIF 格式')
    return false
  }
  
  if (!isLt2M) {
    ElMessage.error('上传头像图片大小不能超过 2MB')
    return false
  }
  
  const reader = new FileReader()
  reader.readAsDataURL(file)
  reader.onload = (e) => {
    cropperOptions.img = e.target.result
    cropperVisible.value = true
  }
  
  return false // 阻止自动上传
}

// 实时预览
const realTime = (data) => {
  preview.div = data.div
}

// 旋转
const rotateLeft = () => {
  cropperRef.value.rotateLeft()
}

const rotateRight = () => {
  cropperRef.value.rotateRight()
}

// 缩放
const zoomIn = () => {
  cropperRef.value.zoomIn()
}

const zoomOut = () => {
  cropperRef.value.zoomOut()
}

// 上传头像
const uploadAvatar = async () => {
  const base64 = cropperRef.value.getCropData()
  
  try {
    loading.value = true
    const formData = new FormData()
    // 将base64转换为Blob
    const blob = dataURLtoBlob(base64)
    formData.append('avatar', blob, 'avatar.png')
    
    const res = await uploadUserAvatar(formData)
    ElMessage.success('头像上传成功')
    user.avatar = res.data.avatar
    // 更新store中的头像
    userStore.setAvatar(res.data.avatar)
  } catch (error) {
    console.error('上传头像失败:', error)
    ElMessage.error('上传头像失败')
  } finally {
    loading.value = false
  }
}

// base64转blob
const dataURLtoBlob = (dataURL) => {
  const arr = dataURL.split(',')
  const mime = arr[0].match(/:(.*?);/)[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  
  return new Blob([u8arr], { type: mime })
}

onMounted(() => {
  getUser()
})
</script>

<style lang="scss" scoped>
.app-container {
  padding: 20px;
}

.box-card {
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  
  .text-center {
    text-align: center;
    padding: 10px 0;
    
    .user-info {
      margin-top: 10px;
      
      h2 {
        margin: 10px 0;
        font-size: 20px;
      }
      
      .user-dept, .user-role {
        color: #606266;
        font-size: 14px;
        margin-bottom: 5px;
      }
    }
  }
  
  .user-statistic {
    display: flex;
    justify-content: space-around;
    margin-top: 20px;
    padding: 20px 0;
    border-top: 1px solid #eee;
    
    .statistic-item {
      text-align: center;
      
      .statistic-number {
        font-size: 24px;
        font-weight: bold;
        color: #409EFF;
      }
      
      .statistic-title {
        font-size: 14px;
        color: #606266;
        margin-top: 5px;
      }
    }
  }
}

.basic-form, .password-form {
  max-width: 600px;
  margin: 20px 0;
}

.avatar-uploader {
  .avatar-container {
    display: flex;
    margin-bottom: 20px;
    
    .cropper-container {
      width: 400px;
      height: 300px;
      border: 1px solid #eee;
    }
    
    .preview-container {
      margin-left: 20px;
      
      .preview-title {
        margin-bottom: 10px;
      }
      
      .preview-box {
        overflow: hidden;
        border: 1px solid #eee;
        
        &.large {
          width: 100px;
          height: 100px;
          margin-bottom: 10px;
        }
        
        &.small {
          width: 50px;
          height: 50px;
        }
      }
    }
  }
  
  .avatar-controls {
    max-width: 500px;
  }
}
</style> 